gocheck 的使用

这篇文章本来两周前就要写的,最近忙一直没时间记录下来,今天有空把它不起来.

前些天倒腾 Sequence 服务的部署,发现 IDE 里面有 gocheck 这个玩意,自己看看发现原来是 go 的一个测试框架,试用用了一下,还不错的,也分享一下.

首先千篇一律的开场,

如果安装

1
go get gopkg.in/check.v1

如果已经安装过了就带上 -u 的参数

1
go get -u gopkg.in/check.v1

如何使用

1
2
3
4
5
import "gopkg.in/check.v1"
func Test(t *testing.T) {
check.TestingT(t)
}

当然官网上的例子是直接吧 gocheck 引入到根下面:

1
import . "gopkg.in/check.v1"

这样做的好处是不用每次调用 gocheck 的时候打包名,但是在实际使用过程中比较不爽的是,提示会不全,毕竟不看过源码谁也不知道里面有哪些方法.

整个测试里面只需要用到一个 Test 方法作为入口,然后调用 check.Testing就好了. 通过这个方法, gocheck 会检查所有注册的测试方法,编写测试方法的规则和 golang 原生的 Test 方式一样,只是参数变成了 *check.C,如下:

1
2
Test*(c *check.C)
Benchmark*(c *chcek.C)

写过 go test 的对这个算是无成本迁移

再说说 gocheck 比较好的地方,

优势

gocheck可以按照用例组(suite)的方式来测试,并且还提供了四个方法,用于在测试前的数据准备和测试后的数据清理

首先你需要创建一个用例组:

1
var _ = check.Suite(&SequenceSuite{})

然后你可以调用下面四个方法对对测试的数据或者对象进行预热或者清理回收

1
2
3
4
func (s *SuiteType) SetUpSuite(c *C) //用例组数据或对象准备
func (s *SuiteType) SetUpTest(c *C) //单用例数据或对象准备
func (s *SuiteType) TearDownTest(c *C) //单用例后续数据回收及对象清理
func (s *SuiteType) TearDownSuite(c *C) //用例组数据回收及对象清理

有了这些方法, golang 的测试就变得简单了,不用绞尽脑汁的像做一个业务测试的时候,如何在用例的前面做数据准备,测试完如何清理掉产生的垃圾数据以及内存回收,这一切 gocheck 都帮你准备好了.

语法糖

其实这里说的语法糖就是断言,这个是由 gocheck 提供的,它已经内置了一些实现,你也可以自己根据需要在自己的公用包里面扩展,看看接口定义:

1
2
3
4
5
6
7
8
9
type CheckerInfo struct {
Name string
Params []string
}
type Checker interface {
Info() *CheckerInfo
Check(params []interface{}, names []string) (result bool, error string)
}

如果在测试的时候需要对结果值进行判断的话,可以用

1
func (c *C) Assert(obtained interface{}, checker Checker, args ...interface{})

这个方法来判断,内置的 Check 接口实现有:

  • DeepEquals
  • Equals
  • ErrorMatches
  • FitsTypeOf
  • HasLen
  • Implements
  • IsNil
  • Matches
  • NotNil
  • PanicMatches

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
c.Assert(value, DeepEquals, 42)
c.Assert(array, DeepEquals, []string{"hi", "there"})
c.Assert(value, Equals, 42)
c.Assert(err, ErrorMatches, "perm.*denied")
c.Assert(value, FitsTypeOf, int64(0))
c.Assert(value, FitsTypeOf, os.Error(nil))
c.Assert(list, HasLen, 5)
var e os.Error
c.Assert(err, Implements, &e)
c.Assert(err, IsNil)
c.Assert(err, Matches, "perm.*denied")
c.Assert(iface, NotNil)
c.Assert(func() { f(1, 2) }, PanicMatches, `open.*: no such file or directory`).

另外还有一个接口是

1
func Not(checker Checker) Checker

用法:

1
c.Assert(a, Not(Equals), b)

这个就不详细解释了.看看就明白.

运行参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
-check.b
Run benchmarks
-check.bmem
Report memory benchmarks
-check.btime duration
approximate run time for each benchmark (default 1s)
-check.f string
Regular expression selecting which tests and/or suites to run
-check.list
List the names of all tests that will be run
-check.v
Verbose mode
-check.vv
Super verbose mode (disables output caching)
-check.work
Display and do not remove the test working directory

这里需要注意的时候 benchmark 的运行在正常的 test 里面不会跑,必须加上 check.b的参数才会跑,但是这样它并不会跑单个的测试用例,这一点在使用过程中需要注意.

coverage 的支持

由于 gocheck 本身就是 golang 原生测试的基础上做的扩展,所以在 coverage 的支持上和 golang 原生的是一致的,这个也是可以放心使用.

坚持原创技术分享,您的支持将鼓励我继续创作!